package com.fishingwithme.android.data.repository

import android.util.Log
import com.fishingwithme.android.data.model.AddCircleDto
import com.fishingwithme.android.data.model.ApproveRuleItem
import com.fishingwithme.android.data.model.AuditCircle
import com.fishingwithme.android.data.model.AuditRequestDto
import com.fishingwithme.android.data.model.Auditor
import com.fishingwithme.android.data.model.CandidateUser
import com.fishingwithme.android.data.model.CircleAuditAdd
import com.fishingwithme.android.data.model.CircleDetail
import com.fishingwithme.android.data.model.CircleMessage
import com.fishingwithme.android.data.model.CirclePageDto
import com.fishingwithme.android.data.model.City
import com.fishingwithme.android.data.model.Comment
import com.fishingwithme.android.data.model.CreditAction
import com.fishingwithme.android.data.model.CreditAvailable
import com.fishingwithme.android.data.model.FishingRecord
import com.fishingwithme.android.data.model.HarvestApprovalDto
import com.fishingwithme.android.data.model.HarvestRecordDto
import com.fishingwithme.android.data.model.HarvestSubmission
import com.fishingwithme.android.data.model.Line
import com.fishingwithme.android.data.model.MyCircleDto
import com.fishingwithme.android.data.model.MyHarvestDto
import com.fishingwithme.android.data.model.MySpotDto
import com.fishingwithme.android.data.model.PageResponse
import com.fishingwithme.android.data.model.PointsRecord
import com.fishingwithme.android.data.model.PolygonOrigin
import com.fishingwithme.android.data.model.Position
import com.fishingwithme.android.data.model.RegisterRequest
import com.fishingwithme.android.data.model.RegisterResponse
import com.fishingwithme.android.data.model.Spot
import com.fishingwithme.android.data.model.SpotAddDTO
import com.fishingwithme.android.data.model.SpotApprovalDto
import com.fishingwithme.android.data.model.SpotDetail
import com.fishingwithme.android.data.model.SpotInCircleDto
import com.fishingwithme.android.data.model.SpotProperty
import com.fishingwithme.android.data.model.SpotUpdateDTO
import com.fishingwithme.android.data.model.UserCredit
import com.fishingwithme.android.data.network.FishingApiService
import com.fishingwithme.android.data.network.NetworkModule.IMAGE_BASE_URL
import com.fishingwithme.android.data.network.UnauthorizedException
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.isActive
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import retrofit2.Response
import java.io.File
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.coroutines.coroutineContext
import kotlin.math.log

@Singleton
class FishingRepository @Inject constructor(
    val apiService: FishingApiService
) {

    val gson = Gson();
    fun loadAddSpotProperties(): Flow<Result<SpotProperty>> = flow {
        try {
            val response = apiService.loadAddSpotProperties()

            if (response.isSuccessful) {
                val props = response.body()
                if (props != null) {
                    // 检查协程是否活跃，避免已取消的协程中发射数据
                    if (coroutineContext.isActive) {
                        val rs: Result<SpotProperty> = Result.success(props)
                        emit(rs)
                    }
                } else {
                    throw Exception("加载属性失败：响应体为空，状态码: ${response.code()}")
                }
            } else {
                throw Exception("加载属性失败：HTTP错误，状态码: ${response.code()}, 消息: ${response.message()}")
            }
        } catch (e: Exception) {
            // 异常情况也通过Result发射，而非直接抛出
            if (coroutineContext.isActive) {
                emit(
                    Result.failure(
                        Exception("加载属性失败: ${e.message ?: "未知错误"}", e)
                    )
                )
            }
        }
    }.flowOn(Dispatchers.IO)

    // 修复：移除多余的suspend修饰符
    fun addSpot(spot: SpotAddDTO): Flow<Result<String>> = flow {
        try {
            val response = apiService.addSpot(spot)

            if (response.isSuccessful) {
                val body = response.body()
                if (body != null && body.status == 1) {
                    if (coroutineContext.isActive) {
                        emit(Result.success(body.data))
                    }
                } else {
                    val errorMsg =
                        "保存钓点失败：无效响应，状态: ${body?.status ?: "null"}, 状态码: ${response.code()}"
                    if (coroutineContext.isActive) {
                        emit(Result.failure(Exception(errorMsg)))
                    }
                }
            } else {
                val errorMsg =
                    "保存钓点失败：HTTP错误，状态码: ${response.code()}, 消息: ${response.message()}"
                if (coroutineContext.isActive) {
                    emit(Result.failure(Exception(errorMsg)))
                }
            }
        } catch (e: Exception) {
            if (coroutineContext.isActive) {
                emit(
                    Result.failure(
                        Exception("保存钓点失败: ${e.message ?: "未知错误"}", e)
                    )
                )
            }
        }
    }

    // Circle and Location APIs
    suspend fun getCityByPosition(location: Position): Flow<Result<City>> = flow {
        try {

            val response = apiService.getCityByPosition(location.latitude, location.longitude)

            if (response.isSuccessful && response.body()?.status == 1) {

                emit(Result.success(response.body()!!.data))

            } else {
                val errorMsg = response.body()?.msg ?: "Failed to get city"

                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            // Only log if it's not a normal flow completion
            if (e.message?.contains("Flow was aborted") != true) {

                emit(Result.failure(e))
            } else {
                Log.d("FishingRepository", "Flow completed normally (aborted after first element)")
            }
        }
    }

    suspend fun searchCities(keyword: String): Flow<Result<List<City>>> = flow {
        try {
            val response = apiService.searchCities(keyword)

            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to search cities"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            // Only log if it's not a normal flow completion
            if (e.message?.contains("Flow was aborted") != true) {
                emit(Result.failure(e))
            } else {
                Log.d(
                    "FishingRepository",
                    "Search flow completed normally (aborted after first element)"
                )
            }
        }
    }

    suspend fun loadCircleMessagesByCity(cityCode: String): Flow<Result<List<CircleMessage<*>>>> =
        flow {
            try {
                Log.d("FishingRepository", "Loading circle messages for city: $cityCode")
                val response = apiService.loadCircleMessages(cityCode)
                Log.d(
                    "FishingRepository",
                    "Messages API response: isSuccessful=${response.isSuccessful}, code=${response.code()}"
                )

                if (response.isSuccessful) {
                    val messages = response.body() ?: emptyList()
                    Log.d("FishingRepository", "Successfully loaded ${messages.size} messages")
                    emit(Result.success(messages))
                } else {
                    Log.e(
                        "FishingRepository",
                        "HTTP error: ${response.code()} ${response.message()}"
                    )
                    emit(Result.failure(Exception("HTTP error: ${response.code()} ${response.message()}")))
                }

            } catch (e: Exception) {
                if (e.message?.contains("Flow was aborted") != true) {
                    Log.e("FishingRepository", "Messages loading exception: ${e.message}", e)
                    emit(Result.failure(e))
                } else {
                    Log.d("FishingRepository", "Messages flow completed normally")
                }
            }
        }


    suspend fun getCircleLocations(location: Position): Flow<Result<List<PolygonOrigin>>> = flow {
        try {
            val response = apiService.getCircleLocations(location.latitude, location.longitude)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to get circle locations"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun getCircles(
        pageNum: Int, 
        pageSize: Int,
        title: String? = null,
        cityCode: String? = null,
        isActive: Boolean? = null
    ): Flow<Result<PageResponse<CirclePageDto>>> = flow {
        try {
            val response = apiService.getCircles(pageNum, pageSize, title, cityCode, isActive)

            if (response.isSuccessful) {
                emit(Result.success(response.body()!!))
            } else {
                val errorMsg = "Failed to get circles"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            if (e.message?.contains("Flow was aborted") != true) {
                emit(Result.failure(e))
            } else {
                Log.d(
                    "FishingRepository",
                    "Flow completed normally (aborted after first element)"
                )
            }
        }
    }

    fun addCircle(circle: AddCircleDto): Flow<Result<String>> = flow {
        try {
            val response = apiService.addCircle(circle)
            val body = response.body()
            if (response.isSuccessful && body != null && body.status == 1) {
                emit(Result.success(body.data ))
            } else {
                if (coroutineContext.isActive) {
                    emit(Result.failure(Exception("Failed to add circle")))
                }
            }
        } catch (e: Exception) {
            Log.d("返回时错误","error")
        }
    }

    suspend fun deleteCircle(id: String): Flow<Result<String>> = flow {
        try {
            val response = apiService.deleteCircle(id)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to delete circle")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun markActive(data: Map<String, String>): Flow<Result<String>> = flow {
        try {
            val response = apiService.markActive(data)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to mark active")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun sendCircleMessage(circleId: String, message: String): Flow<Result<String>> = flow {
        try {
            val request = mapOf("circleId" to circleId, "message" to message)
            val response = apiService.sendCircleMessage(request)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to send message"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    // Circle Messages
    suspend fun loadCircleMessages(cityCode: String): Flow<Result<List<CircleMessage<*>>>> = flow {
        try {
            val response = apiService.loadCircleMessages(cityCode)
            if (response.isSuccessful) {
                val messages = response.body() ?: emptyList()
                emit(Result.success(messages))
            } else {
                emit(Result.failure(Exception("Failed to load messages")))
            }
        } catch (e: UnauthorizedException) {
            // Re-throw UnauthorizedException so it can be handled by the ViewModel
            throw e
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun loadBackwardMessages(
        cityCode: String,
        cursor: String
    ): Flow<Result<List<CircleMessage<*>>>> = flow {
        try {
            val response = apiService.loadBackwardMessages(cityCode, cursor, false)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to load backward messages")))
            }
        } catch (e: UnauthorizedException) {
            throw e
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun loadForwardMessages(
        cityCode: String,
        cursor: String
    ): Flow<Result<List<CircleMessage<*>>>> = flow {
        try {
            val response = apiService.loadForwardMessages(cityCode, cursor, true)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to load forward messages")))
            }
        } catch (e: UnauthorizedException) {
            // Re-throw UnauthorizedException so it can be handled by the ViewModel
            throw e
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    // Spot APIs
    suspend fun loadSpots(latitude: Double, longitude: Double): Flow<Result<List<Spot>>> = flow {
        try {
            val response = apiService.loadSpots(latitude, longitude)
            if (response.isSuccessful) {
                val res = response.body();
                if (res != null) {
                    emit(Result.success(res))
                } else {
                    val errorMsg = "没有数据"
                    emit(Result.failure(Exception(errorMsg)))
                }
            } else {
                val errorMsg = "Failed to load spots"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun loadUserSpots(latitude: Double, longitude: Double): Flow<Result<List<Spot>>> =
        flow {
            try {
                val response = apiService.loadUserSpots(latitude, longitude)
                if (response.isSuccessful && response.body()?.status == 1) {
                    emit(Result.success(response.body()!!.data))
                } else {
                    emit(Result.failure(Exception("Failed to load user spots")))
                }
            } catch (e: Exception) {
                emit(Result.failure(e))
            }
        }

    suspend fun loadSecretSpots(latitude: Double, longitude: Double): Flow<Result<List<Spot>>> =
        flow {
            try {
                val response = apiService.loadSecretSpots(latitude, longitude)
                if (response.isSuccessful && response.body()?.status == 1) {
                    emit(Result.success(response.body()!!.data))
                } else {
                    emit(Result.failure(Exception("Failed to load secret spots")))
                }
            } catch (e: Exception) {
                emit(Result.failure(e))
            }
        }

    suspend fun loadDiscoverSpot(spotId: String): Flow<Result<Spot>> = flow {
        try {
            val response = apiService.loadDiscoverSpot(spotId)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to load discover spot")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun loadUserSpot(spotId: String): Flow<Result<SpotDetail>> = flow {
        try {
            val response = apiService.loadUserSpot(spotId)
            if (response.isSuccessful) {
                val spot: SpotDetail? = response.body();
                if (spot != null) {
                    val rs: Result<SpotDetail> = Result.success(spot)
                    emit(rs)
                } else {
                    emit(Result.failure(Exception("Failed to load user spot")))
                }

            } else {
                emit(Result.failure(Exception("Failed to load user spot")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }


    suspend fun updateSpotDetailed(spotUpdateDTO: SpotUpdateDTO): Flow<Result<String>> = flow {
        try {

            val response = apiService.updateSpot(spotUpdateDTO)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to update spot")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun collectSpot(spotId: String): Flow<Result<String>> = flow {
        try {
            val response = apiService.collectSpot(spotId)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to collect spot")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun queryUserSpots(queryStr: String): Flow<Result<List<Spot>>> = flow {
        try {
            val request = mapOf("query" to queryStr)
            val response = apiService.queryUserSpots(request)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to query spots")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun searchSpots(queryStr: String): Flow<Result<List<Spot>>> = flow {
        try {

            val response = apiService.searchSpots(queryStr)

            if (response.isSuccessful && response.body()?.status == 1) {
                val spots = response.body()!!.data

                emit(Result.success(spots))
            } else {

                emit(Result.failure(Exception("Failed to search spots")))
            }
        } catch (e: Exception) {

            emit(Result.failure(e))
        }
    }

    suspend fun getCircleSpots(
        circleId: String,
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<SpotInCircleDto>>> = flow {
        try {
            val response = apiService.getCircleSpots(circleId, pageNum, pageSize)
            if (response.isSuccessful) {
                val res = response.body()
                if (res != null) {

                    emit(Result.success(res))
                }
            } else {
                val errorMsg =  "Failed to get circle spots"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching spot page", e)
            throw e
        }
    }

    suspend fun getAuditorPage(
        pageNum: Int,
        pageSize: Int,
        isCollected: Boolean
    ): Flow<Result<PageResponse<Auditor>>> = flow {
        try {
            val response = apiService.getAuditorPage(pageNum, pageSize, isCollected)
            if (response.isSuccessful) {
                val res = response.body()
                if (res != null) {

                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("Failed to load spots - null response")))
                }
            } else {

                emit(Result.failure(Exception("Failed to load spots - HTTP ${response.code()}")))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching spot page", e)
            // Instead of emitting Result.failure, we should throw the exception
            // to maintain flow exception transparency
            throw e
        }
    }

    suspend fun getSpotMaintainerPage(
        pageNum: Int,
        pageSize: Int,
        isCollected: Boolean
    ): Flow<Result<PageResponse<SpotApprovalDto>>> = flow {
        try {
            val response = apiService.getApprovalSpots(pageNum, pageSize, isCollected)
            if (response.isSuccessful) {
                val res = response.body()
                if (res != null) {

                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("Failed to load spots - null response")))
                }
            } else {

                emit(Result.failure(Exception("Failed to load spots - HTTP ${response.code()}")))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching spot page", e)
            // Instead of emitting Result.failure, we should throw the exception
            // to maintain flow exception transparency
            throw e
        }
    }
    suspend fun getMyCirclePage(
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<MyCircleDto>>> = flow {
        try {
            val response = apiService.getMyCircles(pageNum, pageSize)
            if (response.isSuccessful) {
                val res = response.body()
                if (res != null) {

                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("Failed to load harvests - null response")))
                }
            } else {

                emit(Result.failure(Exception("Failed to load harvests - HTTP ${response.code()}")))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching harvest page", e)
            throw e
        }
    }
    suspend fun getMyHarvestPage(
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<MyHarvestDto>>> = flow {
        try {
            val response = apiService.getMyHarvests(pageNum, pageSize)
            if (response.isSuccessful) {
                val res = response.body()
                if (res != null) {

                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("Failed to load harvests - null response")))
                }
            } else {

                emit(Result.failure(Exception("Failed to load harvests - HTTP ${response.code()}")))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching harvest page", e)
            throw e
        }
    }

    suspend fun getSpotPage(
        pageNum: Int,
        pageSize: Int,
        isCollected: Boolean
    ): Flow<Result<PageResponse<MySpotDto>>> = flow {
        try {
            val response = apiService.getSpotPage(pageNum, pageSize, isCollected)
            if (response.isSuccessful) {
                val res = response.body()
                if (res != null) {

                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("Failed to load spots - null response")))
                }
            } else {

                emit(Result.failure(Exception("Failed to load spots - HTTP ${response.code()}")))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching spot page", e)
            // Instead of emitting Result.failure, we should throw the exception
            // to maintain flow exception transparency
            throw e
        }
    }

    // Credit System
    suspend fun getUserCredit(): Flow<Result<UserCredit>> = flow {
        try {
            val response = apiService.getUserCredit()
            if (response.isSuccessful && response.body() != null) {
                val userCredit: UserCredit? = response.body()
                if (userCredit != null) {
                    emit(Result.success(userCredit))
                } else {
                    emit(Result.failure(Exception("Failed to get user credit")))
                }

            } else {
                emit(Result.failure(Exception("Failed to get user credit")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun checkCreditAvailable(spotId: String): Flow<Result<CreditAvailable>> = flow {
        try {
            val response = apiService.checkCreditAvailable(spotId)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to check credit availability")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun setSpotCredit(spotId: String, credit: Int): Flow<Result<String>> = flow {
        try {
            val response = apiService.setSpotCredit(spotId, credit)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to set spot credit")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun getCreditRecords(
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<PointsRecord>>> = flow {
        Log.d("FishingRepository", "Fetching credit records - page: $pageNum, size: $pageSize")
        val params = mapOf("pageNum" to pageNum.toString(), "pageSize" to pageSize.toString())
        val response = apiService.getCreditRecords(params)

        Log.d(
            "FishingRepository",
            "API response - successful: ${response.isSuccessful}, code: ${response.code()}"
        )
        if (response.isSuccessful) {
            val pageData = response.body()
            Log.d(
                "FishingRepository",
                "Page data - records: ${pageData?.records?.size}, total: ${pageData?.total}"
            )
            if (pageData != null) {
                emit(Result.success(pageData))
            } else {
                Log.e("FishingRepository", "No data received from server")
                emit(Result.failure(Exception("No data received from server")))
            }
        } else {
            val error =
                Exception("Failed to load credit records: ${response.code()} ${response.message()}")
            Log.e("FishingRepository", "API error", error)
            emit(Result.failure(error))
        }
    }

    suspend fun getCreditRules() = flow {
        try {
            val params = mapOf("pageNum" to "1", "pageSize" to "100") // Get all rules in one page
            val response = apiService.getCreditRules(params)

            if (response.isSuccessful) {
                val pageResponse = response.body()
                if (pageResponse != null) {
                    // Handle potential null records by providing an empty list as fallback
                    val rules = pageResponse.records ?: emptyList()
                    emit(Result.success(rules))
                } else {
                    val errorMsg = "Failed to load credit rules: Empty response body"
                    emit(Result.failure(Exception(errorMsg)))
                }
            } else {
                emit(Result.failure(Exception("Failed to load credit rules: ${response.code()} ${response.message()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(Exception("Failed to load credit rules: ${e.message ?: "Unknown error"}")))
        }
    }

    suspend fun getCreditLevels() = flow {
        try {
            val response = apiService.getCreditLvls()

            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse != null && apiResponse.status == 1) {
                    emit(Result.success(apiResponse.data))
                } else {
                    val errorMsg =
                        "Failed to load credit levels: ${apiResponse?.msg ?: "Unknown error"}"
                    emit(Result.failure(Exception(errorMsg)))
                }
            } else {
                emit(Result.failure(Exception("Failed to load credit levels: ${response.code()} ${response.message()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(Exception("Failed to load credit levels: ${e.message ?: "Unknown error"}")))
        }
    }

    suspend fun getRulesItems(ruleId: Int): Flow<Result<List<ApproveRuleItem>>> = flow {
        try {
            val response = apiService.getRulesItems(ruleId)
            if (response.isSuccessful && response.body()?.status == 1) {
                val rules = response.body()?.data ?: emptyList()
                emit(Result.success(rules))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to load rules items"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    // File Upload
    suspend fun uploadFile(file: File): Flow<Result<String>> = flow {
        try {
            val requestFile = file.asRequestBody("image/*".toMediaTypeOrNull())
            val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
            val response = apiService.uploadFile(body)
            if (response.isSuccessful && response.body()?.status == 1) {
                val url = response.body()!!.data["url"] ?: ""
                emit(Result.success("$IMAGE_BASE_URL/$url"))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to upload file"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    /**
     * Load harvest records for a specific spot with pagination
     */
    suspend fun loadSpotHarvestRecords(
        spotId: String,
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<HarvestRecordDto>>> = flow {
        try {
            val response = apiService.loadSpotVisitors(pageNum, pageSize, spotId)
            if (response.isSuccessful) {
                // Convert FishingRecord to HarvestRecordDto
                val pageData = response.body()
                val harvestRecords: List<HarvestRecordDto> =
                    pageData?.records as List<HarvestRecordDto>

                val harvestPageResponse = PageResponse(
                    records = harvestRecords,
                    total = pageData.total,
                    size = pageData.size,
                    current = pageData.current,
                    pages = pageData.pages
                )
                emit(Result.success(harvestPageResponse))
            } else {
                emit(Result.failure(Exception("Failed to load spot harvest records")))
            }
        } catch (e: Exception) {
            Log.e("error", "error:${e.message}")
        }
    }

    suspend fun loadApproveHarvest(id: String): Flow<Result<FishingRecord>> = flow {
        try {
            val response = apiService.loadApproveHarvest(id)
            if (response.isSuccessful) {
                val res: FishingRecord? = response.body()
                if (res != null) {
                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("没有数据.")))
                }
            } else {
                emit(Result.failure(Exception("Failed to load harvest")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun loadHarvest(id: String): Flow<Result<FishingRecord>> = flow {
        try {
            val response = apiService.loadApproveHarvest(id)
            if (response.isSuccessful) {
                val res: FishingRecord? = response.body()
                if (res != null) {
                    emit(Result.success(res))
                } else {
                    emit(Result.failure(Exception("没有数据.")))
                }
            } else {
                emit(Result.failure(Exception("Failed to load harvest")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    fun addVisitHarvest(data: HarvestSubmission): Flow<Result<Boolean>> = flow {
        try {
            val response = apiService.addVisitHarvest(data)
            if (response.isSuccessful) {
                emit(Result.success(true))
            } else {
                emit(Result.failure(Exception("Failed to submit harvest")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }


    // Comments
    suspend fun getSpotCommentPage(
        spotId: String,
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<Comment>>> = flow {
        try {
            val response: Response<PageResponse<Comment>> =
                apiService.getSpotCommentPage(pageNum, pageSize, spotId)
            val rs: PageResponse<Comment>? = response.body();
            if (response.isSuccessful && rs != null) {
                emit(Result.success(rs))
            } else {
                emit(Result.failure(Exception("Failed to get comments")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun commentHarvest(comment: Comment): Flow<Result<String>> = flow {
        try {
            val response = apiService.commentHarvest(comment)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to add comment")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun harvestLike(harvestId: String, isLiked: Boolean): Flow<Result<String>> = flow {
        try {
            val response = if (isLiked) {
                apiService.harvestLike(harvestId)
            } else {
                apiService.harvestDislike(harvestId)
            }
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                emit(Result.failure(Exception("Failed to like/dislike harvest")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun harvestCommentLike(commentId: String, isLiked: Boolean): Flow<Result<String>> =
        flow {
            try {
                val response = if (isLiked) {
                    apiService.likeComment(commentId)
                } else {
                    apiService.unlikeComment(commentId)
                }
                if (response.isSuccessful && response.body()?.status == 1) {
                    emit(Result.success(response.body()!!.data))
                } else {
                    emit(Result.failure(Exception("Failed to like/unlike comment")))
                }
            } catch (e: Exception) {
                emit(Result.failure(e))
            }
        }

    // User Management
    suspend fun saveUserNickName(params: Map<String, String>): Flow<Result<String>> = flow {
        try {
            val response = apiService.saveUserNickName(params)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to save nickname"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun saveUserAvatar(params: Map<String, String>): Flow<Result<String>> = flow {
        try {
            val response = apiService.saveUserAvatar(params)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to save avatar"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun saveUserGender(params: Map<String, String>): Flow<Result<String>> = flow {
        try {
            val response = apiService.saveUserGender(params)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to save gender"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun sendEmailConfirmingCode(params: Map<String, String>): Flow<Result<String>> = flow {
        try {
            val response = apiService.sendEmailConfirmingCode(params)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to send verification code"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun saveUserEmail(params: Map<String, String>): Flow<Result<String>> = flow {
        try {
            val response = apiService.saveUserEmail(params)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to save email"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun register(request: RegisterRequest): Flow<Result<RegisterResponse>> = flow {
        try {
            val response = apiService.register(request)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to register user"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun setAutoSkipAds(skipAds: Boolean): Flow<Result<String>> = flow {
        try {
            val response = apiService.setAutoSkipAds(skipAds)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to update skip ads setting"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun loadSpotNavigationInfo(spotId: String): Line? {
        val response = apiService.loadSpotNavigationInfo(spotId);
        if (response.isSuccessful) {
            return response.body();

        } else {
            throw Exception("Unable to load nav line.")
        }
    }

    suspend fun auditSpot(auditRequest: AuditRequestDto): Flow<Result<Int>> = flow {
        try {
            val response = apiService.auditSpot(auditRequest)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to audit spot"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    // Harvest Approval API
    suspend fun getApprovalHarvests(
        state: Boolean,
        pageNum: Int,
        pageSize: Int
    ): Flow<Result<PageResponse<HarvestApprovalDto>>> = flow {
        try {
            val response = apiService.getApprovalHarvests(state, pageNum, pageSize)
            if (response.isSuccessful) {
                val pageData = response.body()
                if (pageData != null) {
                    emit(Result.success(pageData))
                } else {
                    emit(Result.failure(Exception("Failed to load approval harvests - null response")))
                }
            } else {
                emit(Result.failure(Exception("Failed to load approval harvests - HTTP ${response.code()}")))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while fetching approval harvests", e)
            throw e
        }
    }

    // Harvest Audit API
    suspend fun auditHarvest(auditRequest: AuditRequestDto): Flow<Result<Int>> = flow {
        try {
            val response = apiService.auditHarvest(auditRequest)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to audit harvest"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            Log.e("FishingRepository", "Exception while auditing harvest", e)
            emit(Result.failure(e))
        }
    }

    // Agreement and Privacy Policy
    suspend fun getAgreementOrPrivacyPolicy(type: String): Flow<Result<com.fishingwithme.android.data.model.Agr>> =
        flow {
            try {
                val response = apiService.getAgrPp(type)
                if (response.isSuccessful && response.body()?.status == 1) {
                    emit(Result.success(response.body()!!.data))
                } else {
                    val errorMsg = response.body()?.msg ?: "Failed to load content"
                    emit(Result.failure(Exception(errorMsg)))
                }
            } catch (e: Exception) {
                emit(Result.failure(e))
            }
        }

    // AddCircleAuditScreen APIs
    suspend fun searchAuditCandidates(nickname: String): Flow<Result<List<CandidateUser>>> = flow {
        try {
            val response = apiService.searchAuditCandidates(nickname)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to search audit candidates"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun searchCircleCandidates(title: String): Flow<Result<List<AuditCircle>>> = flow {
        try {
            val response = apiService.searchCircleCandidates(title)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to search circle candidates"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    suspend fun addCircleAudit(
        nickname: String,
        userId: String,
        circleName: String,
        circleId: Long,
        disabled: Boolean
    ): Flow<Result<Int>> = flow {
        try {
            val form = CircleAuditAdd(
                nickname = nickname,
                userId = userId,
                circleName = circleName,
                circleId = circleId,
                disabled = disabled
            )
            val response = apiService.addCircleAudit(form)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to add circle audit"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }


    fun loadPointSettings(): Flow<Result<CreditAction>> = flow {
        try {
            val response = apiService.getPointSettings()
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to search circle candidates"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    fun loadCircleDetail(id: String): Flow<Result<CircleDetail>> = flow {
        try {
            val response = apiService.getCircleDetail(id)
            if (response.isSuccessful && response.body()?.status == 1) {
                emit(Result.success(response.body()!!.data))
            } else {
                val errorMsg = response.body()?.msg ?: "Failed to get circle"
                emit(Result.failure(Exception(errorMsg)))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }
}